package com.wkbb.basic.controller.open;

import com.github.pagehelper.PageInfo;
import com.wkbb.basic.model.DeviceInfo;
import com.wkbb.basic.model.DeviceType;
import com.wkbb.basic.service.*;
import com.wkbb.common.business.BasicBusiness;
import com.wkbb.common.dto.basic.*;
import com.wkbb.basic.vo.DeviceConfigVo;
import com.wkbb.common.base.BaseController;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.VersionConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.enums.ScreenTypeEnum;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.common.utils.StringUtil;
//import com.wkbb.common.vo.DeviceUserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author Lilin
 */
@RestController
@Api(description = "设备模块对外接口")
@RequestMapping("/basic/{apiVersion}/open")
@Slf4j
public class DeviceController extends BaseController {

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private DeviceTypeService deviceTypeService;

    @Autowired
    private DeviceVersionControlService deviceVersionControlService;

    @Autowired
    private UserService userService;

    @Autowired
    private DeviceBoxService deviceBoxService;

    @Autowired
    private DeviceCameraService deviceCameraService;

    @Autowired
    RedisTemplateUtil redisTemplateUtil;

    @ApiOperation(value = "获取设备初始化信息")
    @RequestMapping(value = "/getDeviceConfig", method = RequestMethod.GET)
    public ResultDTO<DeviceConfigVo> getDeviceConfig(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "设备编号", required = true) @RequestParam(name = "deviceCode", required = true) String deviceCode) {
        log.info("***********DeviceController.getDeviceConfig******apiVersion:{},deviceCode:{}", apiVersion, deviceCode);

        try {
            return new ResultDTO<>(deviceInfoService.getConfigByDeviceCode(deviceCode));
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceConfig******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

//    @ApiOperation(value = "查询用户信息")
//    @RequestMapping(value = "/getDeviceUserList", method = RequestMethod.GET)
//    public ResultDTO<List<DeviceUserVo>> getDeviceUserList(
//            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
//            @ApiParam(value = "设备编号", required = true) @RequestParam(name = "deviceCode", required = true) String deviceCode,
//            @ApiParam(value = "角色类型 1教师 2家长 3学生 4职员 5游客", required = false) @RequestParam(name = "roleType", required = false) String roleType) {
//        log.info("***********DeviceController.getDeviceUserList******apiVersion:{},deviceCode:{},roleType:{}", apiVersion, deviceCode, roleType);
//
//        try {
//            DeviceInfo deviceInfo = deviceInfoService.getInfoByDeviceCode(deviceCode);
//            if (deviceInfo == null) {
//                return new ResultDTO<>(ErrorCode.DEVICE_NOT_EXISTS);
//            }
//
//            return new ResultDTO<>(userService.getUserByDeviceOrg(deviceInfo.getOrgId(), null, roleType,null));
//        } catch (Exception e) {
//            log.error("***********DeviceController.getDeviceUserList******", e);
//            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
//        }
//    }

    @ApiOperation(value = "查询设备详情")
    @RequestMapping(value = "/getDeviceInfo", method = RequestMethod.GET)
    public ResultDTO<DeviceInfoDto> getDeviceInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "设备编号", required = true) @RequestParam(name = "deviceCode", required = true) String deviceCode) {
        log.info("***********DeviceController.getDeviceInfo******apiVersion:{},deviceCode:{}", apiVersion, deviceCode);

        try {

            //取缓存
            String deviceRedisKey = BasicBusiness.getDeviceInfoRedisKey(deviceCode);
            DeviceInfoDto deviceInfoDto = (DeviceInfoDto) redisTemplateUtil.get(deviceRedisKey);

            //缓存中没有则取数据库
            if (null == deviceInfoDto) {
                Map<String, Object> params = new HashMap<>(1);
                params.put("deviceCode", deviceCode);

                deviceInfoDto = deviceInfoService.getDtoByParams(params);

                redisTemplateUtil.set(deviceRedisKey,deviceInfoDto);
            }

            return new ResultDTO<>(deviceInfoDto);
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceInfo******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询设备列表")
    @RequestMapping(value = "/getDeviceInfoList", method = RequestMethod.GET)
    public ResultDTO<List<DeviceInfoDto>> getDeviceInfoList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "设备编号", required = false) @RequestParam(name = "deviceCode", required = false) String deviceCode) {
        log.info("***********DeviceController.getDeviceInfoList******apiVersion:{},deviceCode:{}", apiVersion, deviceCode);

        try {
            Map<String, Object> params = new HashMap<>(2);
            if (orgId != null && orgId != 0) {
                params.put("orgId", orgId);
            }
            if (!StringUtil.isNullOrBlank(deviceCode)) {
                params.put("deviceCode", deviceCode);
            }

            return new ResultDTO<>(deviceInfoService.getDtoListByParams(params));
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceInfoList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询设备分页列表")
    @RequestMapping(value = "getDeviceInfoPageList", method = RequestMethod.GET)
    public ResultDTO<PageInfo<DeviceInfoDto>> getDeviceInfoPageList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "组织名称", required = false) @RequestParam(name = "orgName", required = false) String orgName,
            @ApiParam(value = "设备编号", required = false) @RequestParam(name = "deviceCode", required = false) String deviceCode,
            @ApiParam(value = "设备类型名称", required = false) @RequestParam(name = "name", required = false) String name,
            @ApiParam(value = "页码", required = true, defaultValue = "1") @RequestParam(name = "pageNo", required = true, defaultValue = "1") Integer pageNo,
            @ApiParam(value = "每页条数", required = true, defaultValue = "10") @RequestParam(name = "pageSize", required = true, defaultValue = "10") Integer pageSize) {
        log.info("***********DeviceController.getDeviceInfoPageList******apiVersion:{},orgId:{},orgName:{},deviceCode:{}", apiVersion, orgId, orgName, deviceCode);

        try {
            Map<String, Object> params = new HashMap<>(3);
            if (orgId != null && orgId != 0) {
                params.put("orgId", orgId);
            }
            if (!StringUtil.isNullOrBlank(orgName)) {
                params.put("orgName", orgName);
            }
            if (!StringUtil.isNullOrBlank(deviceCode)) {
                params.put("deviceCode", deviceCode);
            }
            if (!StringUtil.isNullOrBlank(name)) {
                params.put("deviceTypeName", name);
            }
            return new ResultDTO<>(deviceInfoService.getDtoPageByParams(params, pageNo, pageSize));
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceInfoPageList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询设备类型列表")
    @RequestMapping(value = "/getDeviceTypeList", method = RequestMethod.GET)
    public ResultDTO<List<DeviceType>> getDeviceTypeList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "设备类型名称", required = false) @RequestParam(name = "name", required = false) String name) {
        log.info("***********DeviceController.getDeviceTypeList******apiVersion:{},name:{}", apiVersion, name);

        try {
            Map<String, Object> params = new HashMap<>(1);
            if (!StringUtil.isNullOrBlank(name)) {
                params.put("name", name);
            }

            return new ResultDTO<>(deviceTypeService.getListByMapParams(params));
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceTypeList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "新增或修改设备")
    @RequestMapping(value = "/saveOrUpdateDeviceInfo", method = RequestMethod.POST)
    public ResultDTO<Long> saveOrUpdateDeviceInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "操作人姓名", required = false) @RequestParam(value = "userName", required = false) String userName,
            @ApiParam(value = "设备信息", required = true) @RequestBody DeviceInfo deviceInfo) {

        log.info("***********DeviceController.addDeviceInfo******apiVersion:{},deviceInfo:{}", apiVersion, deviceInfo);

        try {
            if (StringUtil.isNullOrBlank(deviceInfo.getDeviceCode()) ||
                    deviceInfo.getOrgId() == null || deviceInfo.getOrgId() == 0 ||
                    deviceInfo.getDeviceTypeId() == null || deviceInfo.getDeviceTypeId() == 0) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            //判断设备是否已存在
            DeviceInfo exists = deviceInfoService.getInfoByDeviceCode(deviceInfo.getDeviceCode());
            if (exists != null) {
                if (!StringUtil.isNullOrBlank(userName)) {
                    deviceInfo.setUpdateBy(userName);
                }

                deviceInfo.setId(exists.getId());
                deviceInfoService.update(deviceInfo);
            } else {
                if (!StringUtil.isNullOrBlank(userName)) {
                    deviceInfo.setCreateBy(userName);
                    deviceInfo.setUpdateBy(userName);
                }

                deviceInfoService.insert(deviceInfo);
            }

            //清缓存
            String deviceRedisKey = BasicBusiness.getDeviceInfoRedisKey(deviceInfo.getDeviceCode());
            redisTemplateUtil.delete(deviceRedisKey);

            return new ResultDTO<>(deviceInfo.getId());
        } catch (Exception e) {
            log.error("***********DeviceController.addDeviceInfo******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据版本号和设备编号查询设备升级信息")
    @RequestMapping(value = "/getDeviceVersionInfoByDeviceCode", method = RequestMethod.GET)
    public ResultDTO<Map<String, Object>> getDeviceVersionInfoByDeviceCode(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "设备编号", required = true) @RequestParam(name = "deviceCode", required = true) String deviceCode,
            @ApiParam(value = "版本编号", required = true) @RequestParam(name = "version", required = true) Long version) {
        log.info("***********DeviceController.getDeviceVersionInfoByDeviceCode******apiVersion:{},deviceCode:{},version:{}", apiVersion, deviceCode, version);
        try {
            Map<String, Object> map = new HashMap<>();
            VersionControlDto versionControlDto = deviceVersionControlService.getVersionControlDtoByDeviceCode(deviceCode);

            if (versionControlDto != null && version < versionControlDto.getVersion()) {
                map.put("isNeedUpgrade", true);
                map.put("fileUrl", versionControlDto.getFileUrl());
            } else {
                map.put("isNeedUpgrade", false);
            }

            return new ResultDTO<>(map);
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceVersionInfoByDeviceCode******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "设备上报当前状态接口")
    @RequestMapping(value = "/uploadDeviceInfo", method = RequestMethod.POST)
    public ResultDTO<Object> uploadDeviceInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "设备编号", required = true) @RequestParam(name = "deviceCode", required = true) String deviceCode,
            @ApiParam(value = "软件版本", required = true) @RequestParam(name = "softVer", required = true) String softVer,
            @ApiParam(value = "硬件版本", required = true) @RequestParam(name = "hardVer", required = true) String hardVer,
            @ApiParam(value = "设备序列号", required = true) @RequestParam(name = "serial", required = true) String serial,
            @ApiParam(value = "是否微众设备", required = false) @RequestParam(name = "webank", required = false, defaultValue = "false") Boolean webank,
            @ApiParam(value = "摄像头:单目1,双目0", required = false) @RequestParam(name = "binocularOrMonocularCamera", required = false, defaultValue = "false") Boolean binocularOrMonocularCamera,
            @ApiParam(value = "是否微众活体", required = false) @RequestParam(name = "live", required = false, defaultValue = "false") Boolean live) {
        log.info("***********DeviceController.uploadDeviceInfo******apiVersion:{},deviceId:{},softVer:{},hardVer:{},serial:{},webank:{},live:{},binocularOrMonocularCamera:{}",
                apiVersion, deviceCode, softVer, hardVer, serial, webank, live, binocularOrMonocularCamera);
        try {
            return deviceInfoService.uploadDeviceInfo(deviceCode, softVer, hardVer, serial, webank, live,binocularOrMonocularCamera,apiVersion);
        } catch (Exception e) {
            log.error("***********DeviceController.uploadDeviceInfo******", e);
            e.printStackTrace();
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询智慧盒子详情")
    @RequestMapping(value = "/getDeviceBoxInfo", method = RequestMethod.GET)
    public ResultDTO<DeviceBoxDto> getDeviceBoxInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "智慧盒子设备编号", required = true) @RequestParam(name = "deviceCode", required = true) String deviceCode) {

        log.info("***********DeviceTypeManageController.getDeviceBoxInfo******apiVersion:{},deviceCode:{}",
                apiVersion, deviceCode);
        try {
            return new ResultDTO<>(deviceBoxService.getDeviceBoxInfo(deviceCode));
        } catch (Exception e) {
            log.error("***********DeviceTypeManageController.getDeviceBoxInfo******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询无感摄像头详情")
    @RequestMapping(value = "/getDeviceCameraInfo", method = RequestMethod.GET)
    public ResultDTO<DeviceCameraDto> getDeviceCameraInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "无感摄像头设备编号", required = true) @RequestParam(name = "deviceCode") String deviceCode) {

        log.info("***********DeviceTypeManageController.getDeviceCameraList******apiVersion:{},deviceCode:{}",
                apiVersion, deviceCode);
        try {
            return new ResultDTO<>(deviceCameraService.getDeviceCameraInfo(deviceCode));
        } catch (Exception e) {
            log.error("***********DeviceTypeManageController.getDeviceCameraList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }


    @ApiOperation(value = "查询学校是否有晨检机设备")
    @RequestMapping(value = "/getOrgIsMcMachine", method = RequestMethod.GET)
    public ResultDTO<Integer> getOrgIsMcMachine(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "机构ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId
    ) {
        log.info("***********DeviceController.getOrgIsMcMachine******apiVersion:{},deviceCode:{},orgId:{}", apiVersion, orgId);
        try {
            Map<String, Object> params = new HashMap<>(5);
            params.put("orgId", orgId);
            Integer res = deviceTypeService.getMorningCheckFlag(params);
            return new ResultDTO<>(res);
        } catch (Exception e) {
            log.error("***********DeviceController.getOrgIsMcMachine******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询无感摄像头列表")
    @RequestMapping(value = "/getDeviceCameraList", method = RequestMethod.GET)
    public ResultDTO<List<DeviceCameraDto>> getDeviceCameraList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "学校名称(模糊查询)", required = false) @RequestParam(name = "orgName", required = false) String orgName,
            @ApiParam(value = "设备编号(模糊查询)", required = false) @RequestParam(name = "deviceCode", required = false) String deviceCode,
            @ApiParam(value = "名称(模糊查询)", required = false) @RequestParam(name = "name", required = false) String name,
            @ApiParam(value = "序列号(模糊查询)", required = false) @RequestParam(name = "serial", required = false) String serial,
            @ApiParam(value = "使用场景", required = false) @RequestParam(name = "scene", required = false) Short scene) {
        log.info("***********DeviceController.getDeviceCameraList******apiVersion:{},orgId:{},orgName:{},deviceCode:{},name:{},serial:{},scene:{}",
                apiVersion, orgId, orgName, deviceCode, name, serial, scene);

        try {
            return new ResultDTO<>(deviceCameraService.getDeviceCameraList(orgId, orgName, deviceCode, name, serial, scene));
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceCameraList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询无感摄像头分页列表")
    @RequestMapping(value = "/getDeviceCameraPageList", method = RequestMethod.GET)
    public ResultDTO<PageInfo<DeviceCameraDto>> getDeviceCameraPageList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "学校名称(模糊查询)", required = false) @RequestParam(name = "orgName", required = false) String orgName,
            @ApiParam(value = "设备编号(模糊查询)", required = false) @RequestParam(name = "deviceCode", required = false) String deviceCode,
            @ApiParam(value = "名称(模糊查询)", required = false) @RequestParam(name = "name", required = false) String name,
            @ApiParam(value = "序列号(模糊查询)", required = false) @RequestParam(name = "serial", required = false) String serial,
            @ApiParam(value = "使用场景", required = false) @RequestParam(name = "scene", required = false) Short scene,
            @ApiParam(value = "页码", required = true, defaultValue = "1") @RequestParam(name = "pageNo", required = true, defaultValue = "1") Integer pageNo,
            @ApiParam(value = "每页条数", required = true, defaultValue = "10") @RequestParam(name = "pageSize", required = true, defaultValue = "10") Integer pageSize) {

        log.info("***********DeviceController.getDeviceCameraPageList******apiVersion:{},orgId:{},orgName:{}," +
                        "deviceCode:{},name:{},serial:{},scene:{},pageNo:{},pageSize:{}",
                apiVersion, orgId, orgName, deviceCode, name, serial, scene, pageNo, pageSize);

        try {
            return new ResultDTO<>(deviceCameraService.getDeviceCameraPageList(orgId, orgName, deviceCode, name, serial, scene, pageNo, pageSize));
        } catch (Exception e) {
            log.error("***********DeviceController.getDeviceCameraPageList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }


    @ApiOperation(value = "查询屏幕类型枚举")
    @RequestMapping(value = "/getScreenType", method = RequestMethod.GET)
    public ResultDTO<Object> getScreenType(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion
    ) {
        log.info("***********DeviceController.getScreenType******apiVersion:{}", apiVersion);

        try {
            Map<Integer, Object> params = new HashMap<>(3);
            params.put(ScreenTypeEnum.SCREENTYPEONE.getValue(), ScreenTypeEnum.SCREENTYPEONE.getDesc());
            params.put(ScreenTypeEnum.SCREENTYPETWO.getValue(), ScreenTypeEnum.SCREENTYPETWO.getDesc());
            params.put(ScreenTypeEnum.SCREENTYPETHREE.getValue(), ScreenTypeEnum.SCREENTYPETHREE.getDesc());
            params.put(ScreenTypeEnum.SCREENTYPEFOUR.getValue(), ScreenTypeEnum.SCREENTYPEFOUR.getDesc());

            return new ResultDTO<>(params);
        } catch (Exception e) {
            log.error("***********DeviceController.getScreenType******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }


    }

    @ApiOperation(value = "查询服务器时间")
    @RequestMapping(value = "/getServerTime", method = RequestMethod.GET)
    public ResultDTO<Object> getServerTime(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion
    ) {
        log.info("***********DeviceController.getServerTime******apiVersion:{}", apiVersion);

        try {
            return new ResultDTO<Object>(System.currentTimeMillis());
        } catch (Exception e) {
            log.error("***********DeviceController.getServerTime******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }


    }

}
